import 'package:device_calendar/device_calendar.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:intl/intl.dart';
import 'package:photo_frame/main.dart';
import 'package:photo_frame/net/model/event_dto.dart';
import 'package:photo_frame/net/model/member_model.dart';
import 'package:photo_frame/provider/schedule_provider.dart';
import 'package:photo_frame/router/router_context.dart';
import 'package:photo_frame/user/user_manager.dart';
import 'package:photo_frame/utils/a_logger.dart';
import 'package:photo_frame/utils/localization_util.dart';
import 'package:photo_frame/widgets/custom_cupertino_alert_dialog.dart';
import 'package:provider/provider.dart';
import 'package:rrule/rrule.dart' as rruleUtil;

class NewScheduleDialog extends StatefulWidget {
  String? frameId;
  EventDTO? event;
  DateTime? startDateTime;
  List<MemberModel> memberList;

  NewScheduleDialog(this.frameId, this.memberList,
      {this.event, this.startDateTime, super.key});

  @override
  State<StatefulWidget> createState() => _NewScheduleDialogState();
}

class _NewScheduleDialogState extends State<NewScheduleDialog> {
  TextEditingController controller = TextEditingController();
  FocusNode node = FocusNode();
  NewScheduleViewModel _vm = NewScheduleViewModel();

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    ALogger.e("_NewScheduleDialogState didChangeDependencies ${widget.event}");
    controller.text = widget.event?.title ?? "";
    _vm.init(
        context: context,
        event: widget.event,
        startDateTime: widget.startDateTime,
        memberList: widget.memberList);
  }

  @override
  Widget build(BuildContext context) {
    return CustomCupertinoAlertDialog(
      title: Stack(
        children: [
          Align(
            child: Text(
              widget.event?.event_id?.isNotEmpty == true
                  ? AppLocalizationsWrapper.instance
                      .unwrapNoCtx()
                      .editScheduleDialogTitle
                  : AppLocalizationsWrapper.instance
                      .unwrapNoCtx()
                      .newScheduleDialogTitle,
              style: TextStyle(
                  fontSize: 16,
                  color: Color(0xff333333),
                  fontWeight: FontWeight.bold),
            ),
          ),
          Visibility(
            visible: widget.event?.event_id?.isNotEmpty == true,
            child: GestureDetector(
              onTap: () {
                _vm.delete(widget.event!).then((e) {
                  ARouter.instance.pagePop(arguments: true);
                }).catchError((_) {});
                node.unfocus();
              },
              child: Align(
                alignment: Alignment.centerRight,
                child: Text(
                  AppLocalizationsWrapper.instance.unwrapNoCtx().deleteSchedule,
                  style: TextStyle(
                      fontSize: 14,
                      color: Color(0xffFF6F6F),
                      fontWeight: FontWeight.bold),
                ),
              ),
            ),
          ),
        ],
      ),
      content: ChangeNotifierProvider(
        create: (BuildContext context) => _vm,
        child: Column(
          children: [
            Container(
              margin: EdgeInsets.only(top: 0),
              height: 44,
              padding: EdgeInsets.symmetric(horizontal: 14),
              decoration: BoxDecoration(
                  color: Color(0xffEAECEE),
                  borderRadius: BorderRadius.circular(10.0)),
              child: TextField(
                maxLines: 1,
                minLines: 1,
                focusNode: node,
                controller: controller,
                style: TextStyle(fontWeight: FontWeight.normal, fontSize: 16),
                decoration: InputDecoration(
                  hintMaxLines: 1,
                  border: InputBorder.none,
                  hintText: AppLocalizationsWrapper.instance
                      .unwrap(context)
                      .inputHintTitle,
                  hintStyle: TextStyle(
                    color: Colors.grey,
                    fontSize: 16,
                  ),
                ),
              ),
            ),
            Padding(
              padding: const EdgeInsets.only(left: 15),
              child: Column(
                children: [
                  SizedBox(height: 9.5),
                  _allDayModeWidget(),
                  _startTimeWidget(),
                  _endTimeWidget(),
                  SizedBox(height: 9.5),
                  _repeatModeWidget(),
                  SizedBox(height: 8),
                  _memberListWidget(),
                  SizedBox(height: 16),
                ],
              ),
            )
          ],
        ),
      ),
      actions: <Widget>[
        CupertinoButton(
          padding: EdgeInsets.zero,
          onPressed: () async {
            _vm
                .submit(widget.frameId ?? "", controller.text, widget.event)
                .then((e) {
              ARouter.instance.pagePop(arguments: true);
            }).catchError((_) {});
            node.unfocus();
          },
          child: Text(
            AppLocalizationsWrapper.instance.unwrapNoCtx().newScheduleConfig,
            style: TextStyle(
                fontSize: 16,
                color: Color(0xff3F74EF),
                fontWeight: FontWeight.bold),
          ),
        ),
      ],
    );
  }

  Widget _allDayModeWidget() {
    return Row(
      crossAxisAlignment: CrossAxisAlignment.center,
      children: [
        Center(
            child: _leftTextWidget(AppLocalizationsWrapper.instance
                .unwrap(context)
                .newScheduleDialogAllDay)),
        Expanded(
          flex: 1,
          child: Align(
            alignment: Alignment.centerRight,
            child: Transform.scale(
              scale: 0.8,
              alignment: Alignment.centerRight,
              child: Selector<NewScheduleViewModel, bool>(
                builder: (BuildContext context, value, Widget? child) {
                  return CupertinoSwitch(
                    value: value,
                    activeColor: Color(0xff3F74EF),
                    onChanged: (bool value) {
                      _vm.setAllDayMode(value);
                    },
                  );
                },
                shouldRebuild: (n1, n2) => n1 != n2,
                selector: (_, vm) => vm._allDayMode,
              ),
            ),
          ),
        ),
      ],
    );
  }

  Widget _startTimeWidget() {
    return Selector<NewScheduleViewModel, TimeModel>(
      builder: (BuildContext context, model, Widget? child) {
        return Padding(
          padding: const EdgeInsets.only(top: 9.5),
          child: Row(
            children: [
              _leftTextWidget(AppLocalizationsWrapper.instance
                  .unwrap(context)
                  .newScheduleDialogStartTime),
              Expanded(
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.end,
                  children: [
                    CupertinoButton(
                      padding: EdgeInsets.zero,
                      onPressed: () async {
                        final duration =
                            await _showDateDialog(model.time, (selected) {
                          return true;
                        });
                        if (duration != null) {
                          _vm.setStarTime(duration);
                          _vm.setEndTime(_vm._endTime.copyWith(
                              year: duration.year,
                              month: duration.month,
                              day: duration.day));
                        }
                      },
                      child: Container(
                        height: 30,
                        decoration: BoxDecoration(
                            color: Color(0xffEAECEE),
                            borderRadius: BorderRadius.circular(10)),
                        padding: EdgeInsets.only(left: 14.5, right: 13.5),
                        alignment: Alignment.center,
                        child: Text(
                          DateFormat.yMMMd(
                                  Localizations.localeOf(context).languageCode)
                              .format(model.time),
                          style: TextStyle(
                            color: Color(0xff333333),
                            fontSize: 12,
                          ),
                          strutStyle: StrutStyle(
                            height: 1.1,
                            forceStrutHeight: true,
                          ),
                        ),
                      ),
                    ),
                    Visibility(
                      visible: model.allDayMode != true,
                      child: CupertinoButton(
                        padding: EdgeInsets.zero,
                        onPressed: () async {
                          final duration = await _showTimeDialog(
                              Duration(
                                  hours: model.time.hour,
                                  minutes: model.time.minute), (selected) {
                            return true;
                          });
                          if (duration != null) {
                            _vm.setStarTime(model.time.copyWith(
                                hour: duration.inHours.remainder(60),
                                minute: duration.inMinutes.remainder(60)));
                          }
                        },
                        child: Container(
                          decoration: BoxDecoration(
                              color: Color(0xffEAECEE),
                              borderRadius: BorderRadius.circular(10)),
                          margin: EdgeInsets.only(left: 5),
                          padding: EdgeInsets.only(left: 14.5, right: 13.5),
                          height: 30,
                          alignment: Alignment.center,
                          child: Text(
                            DateFormat.Hm(Localizations.localeOf(context)
                                    .languageCode)
                                .format(model.time),
                            style: TextStyle(
                                color: Color(0xff333333), fontSize: 12),
                          ),
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            ],
          ),
        );
      },
      shouldRebuild: (n1, n2) => n1 != n2,
      selector: (_, vm) => TimeModel(vm._allDayMode, vm._starTime),
    );
  }

  Widget _endTimeWidget() {
    return Selector<NewScheduleViewModel, TimeModel>(
      builder: (BuildContext context, model, Widget? child) {
        return Padding(
          padding: const EdgeInsets.only(top: 9.5),
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              _leftTextWidget(AppLocalizationsWrapper.instance
                  .unwrap(context)
                  .newScheduleDialogEndTime),
              Expanded(
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.end,
                  children: [
                    Visibility(
                      visible: model.allDayMode,
                      child: CupertinoButton(
                        padding: EdgeInsets.zero,
                        onPressed: () async {
                          final time =
                              await _showDateDialog(model.time, (selected) {
                            // if (selected.isBefore(_vm._endTime)) {
                            //   Fluttertoast.showToast(
                            //       msg: AppLocalizationsWrapper.instance
                            //           .unwrap(context)
                            //           .endTimeLessThanStart);
                            //   return false;
                            // }
                            return true;
                          });
                          if (time != null) {
                            _vm.setEndTime(time);
                          }
                        },
                        child: Container(
                          height: 30,
                          decoration: BoxDecoration(
                              color: Color(0xffEAECEE),
                              borderRadius: BorderRadius.circular(10)),
                          padding: EdgeInsets.only(left: 14.5, right: 13.5),
                          alignment: Alignment.center,
                          child: Text(
                            DateFormat.yMMMd(Localizations.localeOf(context)
                                    .languageCode)
                                .format(model.time),
                            style: TextStyle(
                              color: Color(0xff333333),
                              fontSize: 12,
                            ),
                            strutStyle: StrutStyle(
                              height: 1.1,
                              forceStrutHeight: true,
                            ),
                          ),
                        ),
                      ),
                    ),
                    Visibility(
                      visible: model.allDayMode != true,
                      child: CupertinoButton(
                        padding: EdgeInsets.zero,
                        onPressed: () async {
                          final duration = await _showTimeDialog(
                              Duration(
                                  hours: model.time.hour,
                                  minutes: model.time.minute), (selected) {
                            // final selectedTime = model.time.copyWith(
                            //     hour: selected.inHours.remainder(60),
                            //     minute: selected.inMinutes.remainder(60));
                            // if (_vm._starTime.isAfter(selectedTime)) {
                            //   Fluttertoast.showToast(
                            //       msg: AppLocalizationsWrapper.instance
                            //           .unwrap(context)
                            //           .endTimeLessThanStart);
                            //   return false;
                            // }
                            return true;
                          });
                          if (duration != null) {
                            _vm.setEndTime(model.time.copyWith(
                                hour: duration.inHours.remainder(60),
                                minute: duration.inMinutes.remainder(60)));
                          }
                        },
                        child: Container(
                          decoration: BoxDecoration(
                              color: Color(0xffEAECEE),
                              borderRadius: BorderRadius.circular(10)),
                          margin: EdgeInsets.only(left: 5),
                          padding: EdgeInsets.only(left: 14.5, right: 13.5),
                          height: 30,
                          alignment: Alignment.center,
                          child: Text(
                            DateFormat.Hm(Localizations.localeOf(context)
                                    .languageCode)
                                .format(model.time),
                            style: TextStyle(
                                color: Color(0xff333333), fontSize: 12),
                          ),
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            ],
          ),
        );
      },
      shouldRebuild: (n1, n2) => n1 != n2,
      selector: (_, vm) => TimeModel(vm._allDayMode, vm._endTime),
    );
  }

  Widget _repeatModeWidget() {
    return Selector<NewScheduleViewModel, int>(
      builder: (BuildContext context, mode, Widget? child) {
        return Row(
          children: [
            _leftTextWidget(AppLocalizationsWrapper.instance
                .unwrap(context)
                .newScheduleDialogRepeat),
            Expanded(
              child: Row(
                mainAxisAlignment: MainAxisAlignment.end,
                children: [
                  CupertinoButton(
                    padding: EdgeInsets.zero,
                    onPressed: () async {
                      final mode = await _showSwitchModeActionSheet();
                      if (mode != null) {
                        _vm.setRepeatMode(mode);
                      }
                    },
                    child: Container(
                      decoration: BoxDecoration(
                          color: Color(0xffEAECEE),
                          borderRadius: BorderRadius.circular(10)),
                      margin: EdgeInsets.only(left: 5),
                      padding: EdgeInsets.only(left: 11.5, right: 8),
                      height: 30,
                      alignment: Alignment.center,
                      child: Row(
                        children: [
                          Text(
                            _vm.repeatDesc(context),
                            style: TextStyle(
                                color:
                                    Color(mode == 0 ? 0xff999999 : 0xff333333),
                                fontSize: 12),
                            strutStyle: StrutStyle(
                              height: 1.1,
                              forceStrutHeight: true,
                            ),
                          ),
                          Icon(
                            Icons.keyboard_arrow_down_rounded,
                            size: 16,
                            color: Color(mode == 0 ? 0xff999999 : 0xff333333),
                          ),
                        ],
                      ),
                    ),
                  ),
                ],
              ),
            ),
          ],
        );
      },
      shouldRebuild: (n1, n2) => n1 != n2,
      selector: (_, vm) => vm.repeatMode,
    );
  }

  Widget _memberListWidget() {
    return SizedBox(
      height: 28,
      child: Selector<NewScheduleViewModel, List<MemberModel>>(
          builder: (context, list, child) {
            return ListView.separated(
              scrollDirection: Axis.horizontal,
              itemBuilder: (context, index) {
                var item = list[index];
                return Opacity(
                  opacity: item.selected ? 1 : 0.5,
                  child: CupertinoButton(
                    padding: EdgeInsets.zero,
                    minSize: 0,
                    onPressed: () {
                      _vm.selectMember(index);
                    },
                    child: Container(
                      alignment: Alignment.center,
                      decoration: BoxDecoration(
                        color: Color(item.fixedColor),
                        shape: BoxShape.circle,
                      ),
                      width: 28,
                      height: 28,
                      child: Text(
                        item.name?.isNotEmpty == true
                            ? item.name!.substring(0, 1)
                            : "",
                        style: TextStyle(
                            color: Colors.white,
                            fontSize: 15,
                            fontWeight: FontWeight.bold),
                        strutStyle: StrutStyle(forceStrutHeight: true),
                      ),
                    ),
                  ),
                );
              },
              separatorBuilder: (_, index) => SizedBox(width: 5),
              itemCount: list.length,
            );
          },
          shouldRebuild: (n1, n2) => n1 != n2,
          selector: (_, vm) => vm._memberList),
    );
  }

  Widget _leftTextWidget(String data) {
    return Text(
      data,
      style: TextStyle(color: Color(0xff333333), fontSize: 14),
    );
  }

  Future<DateTime?> _showDateDialog(
      DateTime dateTime, TimeTest<DateTime> test) async {
    DateTime resDateTime = dateTime;
    return showCupertinoModalPopup<DateTime>(
      context: context,
      builder: (BuildContext context) => Container(
        height: 260,
        color: CupertinoColors.systemBackground.resolveFrom(context),
        child: Column(
          children: [
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                CupertinoButton(
                  padding: EdgeInsets.zero,
                  onPressed: () {
                    ARouter.instance.pagePop(arguments: dateTime);
                  },
                  child: Padding(
                    padding: EdgeInsets.symmetric(horizontal: 14, vertical: 8),
                    child: Text(
                        AppLocalizationsWrapper.instance.unwrap(context).cancel,
                        style: TextStyle(color: Colors.grey, fontSize: 16)),
                  ),
                ),
                CupertinoButton(
                  padding: EdgeInsets.zero,
                  onPressed: () async {
                    if (!test(resDateTime)) {
                      return;
                    }
                    ARouter.instance.pagePop(
                        arguments: dateTime.copyWith(
                            year: resDateTime.year,
                            month: resDateTime.month,
                            day: resDateTime.day));
                  },
                  child: Padding(
                    padding: EdgeInsets.symmetric(horizontal: 14, vertical: 8),
                    child: Text(
                        AppLocalizationsWrapper.instance
                            .unwrap(context)
                            .confirm,
                        style:
                            TextStyle(color: Color(0xff3F74EF), fontSize: 16)),
                  ),
                )
              ],
            ),
            SizedBox(
              height: 216,
              child: CupertinoDatePicker(
                use24hFormat: true,
                mode: CupertinoDatePickerMode.date,
                dateOrder: DatePickerDateOrder.ymd,
                minimumDate: DateTime.now().copyWith(
                    hour: 0,
                    minute: 0,
                    second: 0,
                    millisecond: 0,
                    microsecond: 0),
                minimumYear: DateTime.now().year,
                initialDateTime: dateTime,
                onDateTimeChanged: (DateTime value) {
                  resDateTime = value;
                },
              ),
            ),
          ],
        ),
      ),
    );
  }

  Future<Duration?> _showTimeDialog(
      Duration duration, TimeTest<Duration> test) async {
    Duration resDuration = duration;
    return await showCupertinoModalPopup<Duration>(
      context: context,
      builder: (BuildContext context) => Container(
        height: 260,
        color: CupertinoColors.systemBackground.resolveFrom(context),
        child: Column(
          children: [
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                CupertinoButton(
                  padding: EdgeInsets.zero,
                  onPressed: () {
                    ARouter.instance.pagePop(arguments: duration);
                  },
                  child: Padding(
                    padding: EdgeInsets.symmetric(horizontal: 14, vertical: 8),
                    child: Text(
                        AppLocalizationsWrapper.instance.unwrap(context).cancel,
                        style: TextStyle(color: Colors.grey, fontSize: 16)),
                  ),
                ),
                CupertinoButton(
                  padding: EdgeInsets.zero,
                  onPressed: () {
                    if (!test(resDuration)) {
                      return;
                    }
                    ARouter.instance.pagePop(arguments: resDuration);
                  },
                  child: Padding(
                    padding: EdgeInsets.symmetric(horizontal: 14, vertical: 8),
                    child: Text(
                        AppLocalizationsWrapper.instance
                            .unwrap(context)
                            .confirm,
                        style:
                            TextStyle(color: Color(0xff3F74EF), fontSize: 16)),
                  ),
                )
              ],
            ),
            SizedBox(
              height: 216,
              child: CupertinoTimerPicker(
                mode: CupertinoTimerPickerMode.hm,
                initialTimerDuration: duration,
                onTimerDurationChanged: (Duration value) {
                  resDuration = value;
                },
              ),
            ),
          ],
        ),
      ),
    );
  }

  _showSwitchModeActionSheet() {
    return showCupertinoModalPopup<int>(
      context: context,
      builder: (context) => CupertinoActionSheet(
        cancelButton: CupertinoActionSheetAction(
          isDefaultAction: true,
          onPressed: (() {
            Navigator.pop(context);
          }),
          child: Text(
            AppLocalizationsWrapper.instance.unwrap(context).cancel,
            style: TextStyle(
                color: Colors.black,
                fontSize: 16,
                fontWeight: FontWeight.normal),
          ),
        ),
        actions: [
          _switchModeItem(
              AppLocalizationsWrapper.instance
                  .unwrap(context)
                  .newScheduleDialogRepeatModeDay, () {
            ARouter.instance.pagePop(arguments: 1);
          }),
          _switchModeItem(
              AppLocalizationsWrapper.instance
                  .unwrap(context)
                  .newScheduleDialogRepeatModeWeek, () {
            ARouter.instance.pagePop(arguments: 2);
          }),
          _switchModeItem(
              AppLocalizationsWrapper.instance
                  .unwrap(context)
                  .newScheduleDialogRepeatModeMonth, () {
            ARouter.instance.pagePop(arguments: 3);
          }),
          _switchModeItem(
              AppLocalizationsWrapper.instance
                  .unwrap(context)
                  .newScheduleDialogRepeatModeYear, () {
            ARouter.instance.pagePop(arguments: 4);
          }),
          _switchModeItem(
              AppLocalizationsWrapper.instance
                  .unwrap(context)
                  .newScheduleDialogRepeatModeNever, () {
            ARouter.instance.pagePop(arguments: 0);
          }),
        ],
      ),
    );
  }

  _switchModeItem(String name, VoidCallback onPressed) {
    return Container(
      color: Colors.white,
      child: CupertinoActionSheetAction(
        onPressed: onPressed,
        child: Center(
          child: Padding(
            padding: const EdgeInsets.only(left: 8.0),
            child: Text(
              name,
              style: TextStyle(color: Color(0xff333333), fontSize: 14),
            ),
          ),
        ),
      ),
    );
  }
}

class NewScheduleViewModel extends ChangeNotifier {
  late ScheduleViewModel _scheduleViewModel;
  String? eventId;
  bool _allDayMode = false;
  DateTime _starTime = DateTime.now();
  DateTime _endTime = DateTime.now();
  int repeatMode = 0;

  String repeatDesc(BuildContext context) => switch (repeatMode) {
        MODE_DAILY => AppLocalizationsWrapper.instance
            .unwrap(context)
            .newScheduleDialogRepeatModeDay,
        MODE_WEEKLY => AppLocalizationsWrapper.instance
            .unwrap(context)
            .newScheduleDialogRepeatModeWeek,
        MODE_MONTHLY => AppLocalizationsWrapper.instance
            .unwrap(context)
            .newScheduleDialogRepeatModeMonth,
        MODE_YEARLY => AppLocalizationsWrapper.instance
            .unwrap(context)
            .newScheduleDialogRepeatModeYear,
        _ => AppLocalizationsWrapper.instance
            .unwrap(context)
            .newScheduleDialogRepeatModeNever,
      };

  List<MemberModel> _memberList = [];

  init(
      {required BuildContext context,
      required EventDTO? event,
      required DateTime? startDateTime,
      required List<MemberModel> memberList}) {
    eventId = event?.event_id;
    ALogger.e(
        "submit-e : - > ${DateTime.fromMillisecondsSinceEpoch(event?.dtstart ?? 0, isUtc: true).toLocal()} ${DateTime.fromMillisecondsSinceEpoch(event?.dtend ?? 0, isUtc: true).toLocal()} ${event?.dtend}");
    try {
      int mode = MODE_NEVER;
      var recurrenceRule = event?.toRecurrenceRule();
      if (recurrenceRule != null) {
        mode = getRecurrenceMode(recurrenceRule);
      }
      setRepeatMode(mode);
    } catch (e) {
      ALogger.e(e);
    }
    setAllDayMode(event?.allDay == 1);

    setStarTime(DateTime.fromMillisecondsSinceEpoch(
            event?.dtstart ??
                startDateTime?.millisecondsSinceEpoch ??
                DateTime.now().millisecondsSinceEpoch,
            isUtc: true)
        .toLocal());

    DateTime startTimeAddOne() {
      var add = _starTime.copyWith().add(Duration(hours: 1));
      if (add.day != _starTime.day) {
        return add.copyWith(hour: 23, minute: 59, second: 59);
      }
      return add;
    }

    setEndTime(DateTime.fromMillisecondsSinceEpoch(
            event?.dtend ?? startTimeAddOne().millisecondsSinceEpoch,
            isUtc: true)
        .toLocal());
    setMemberList(memberList.map((e) {
      e.selected = event?.memberList.contains(e.id.toString()) ?? false;
      return e;
    }).toList());
    _scheduleViewModel = context.read<ScheduleViewModel>();
  }

  setStarTime(DateTime time) {
    _starTime = time;
    notifyListeners();
  }

  setEndTime(DateTime time) {
    _endTime = time;
    notifyListeners();
  }

  setMemberList(List<MemberModel> memberList) {
    _memberList = memberList;
    notifyListeners();
  }

  setAllDayMode(bool allDayMode) {
    _allDayMode = allDayMode;
    setEndTime(_starTime);
    notifyListeners();
  }

  setRepeatMode(int mode) {
    repeatMode = mode;
    notifyListeners();
  }

  selectMember(int index) {
    for (int i = 0; i < _memberList.length; i++) {
      _memberList[i].selected = i == index;
    }
    _memberList = _memberList.toList();
    notifyListeners();
  }

  Future<void> delete(EventDTO originEvent) async {
    await EasyLoading.show(
      maskType: EasyLoadingMaskType.black,
    );
    await _scheduleViewModel.delete([originEvent]).then((e) {
      EasyLoading.dismiss();
    }).catchError((e) {
      print(e);
      EasyLoading.dismiss();
    });
  }

  Future<void> submit(
      String frameId, String title, EventDTO? originEvent) async {
    if (title.isEmpty) {
      Fluttertoast.showToast(
          msg: AppLocalizationsWrapper.instance
              .unwrapNoCtx()
              .newScheduleTitleTips);
      throw ArgumentError("title empty");
    }
    if (_memberList.where((e) => e.selected).isEmpty) {
      Fluttertoast.showToast(
          msg: AppLocalizationsWrapper.instance
              .unwrapNoCtx()
              .newScheduleChooseMemberTips);
      throw ArgumentError("memberList empty");
    }
    var dtstart = _allDayMode ? normalizeToMidnight(_starTime)
        .millisecondsSinceEpoch : _starTime.millisecondsSinceEpoch;
    var dtend = _allDayMode
        ? normalizeToEndOfDay(_endTime).millisecondsSinceEpoch
        : _endTime.millisecondsSinceEpoch;

    if (dtend <dtstart) {
      Fluttertoast.showToast(
          msg: AppLocalizationsWrapper.instance
              .unwrapNoCtx()
              .endTimeLessThanStart);
      throw ArgumentError("End time must be later than start time");
    }

    await EasyLoading.show(
      maskType: EasyLoadingMaskType.black,
    );
    ALogger.e("submit : - > ${_starTime} ${_endTime}");
    originEvent ??= EventDTO();

    originEvent
      ..frame_id = frameId
      ..title = title
      ..dtstart = dtstart
      ..dtend = dtend
      ..eventTimezone = DateTime.now().timeZoneName
      ..attendees =
          _memberList.where((e) => e.selected).map((e) => e.id).join(",")
      ..rrule = _convertRecurrenceRule(repeatMode)
      ..allDay = _allDayMode ? 1 : 0;
    originEvent.setupFotocubeCalendarType();
    Future<void> future;
    if (eventId?.isNotEmpty == true) {
      future = _scheduleViewModel.update(originEvent);
    } else {
      future = _scheduleViewModel.add(originEvent);
    }
    return future.then((e) {
      EasyLoading.dismiss();
    }).catchError((e) {
      print(e);
      EasyLoading.dismiss();
      Fluttertoast.showToast(
          msg: AppLocalizationsWrapper.instance.unwrapNoCtx().netError);
      throw e;
    });
  }

  _convertRecurrenceRule(int mode) {
    switch (mode) {
      case MODE_DAILY:
        var ruleStr = rruleUtil.RecurrenceRule(
          frequency: rruleUtil.Frequency.daily,
          until: _endTime.toUtc(),
          byHours: [_starTime.hour],
          byMinutes: [_starTime.minute],
        ).toString();
        return ruleStr.substring("RRULE:".length, ruleStr.length);
      case MODE_WEEKLY:
        var ruleStr = rruleUtil.RecurrenceRule(
          frequency: rruleUtil.Frequency.weekly,
          until: _endTime.toUtc(),
          byWeekDays: [rruleUtil.ByWeekDayEntry(_starTime.weekday)],
          byHours: [_starTime.hour],
          byMinutes: [_starTime.minute],
        ).toString();
        return ruleStr.substring("RRULE:".length, ruleStr.length);
      case MODE_MONTHLY:
        var ruleStr = rruleUtil.RecurrenceRule(
          frequency: rruleUtil.Frequency.monthly,
          until: _endTime.toUtc(),
          byMonthDays: [_starTime.day],
          byHours: [_starTime.hour],
          byMinutes: [_starTime.minute],
        ).toString();
        return ruleStr.substring("RRULE:".length, ruleStr.length);
      case MODE_YEARLY:
        var ruleStr = rruleUtil.RecurrenceRule(
          frequency: rruleUtil.Frequency.yearly,
          until: _endTime.toUtc(),
          byYearDays: [_starTime.day],
          byHours: [_starTime.hour],
          byMinutes: [_starTime.minute],
        ).toString();
        return ruleStr.substring("RRULE:".length, ruleStr.length);
      default:
        return null;
    }
  }
}

typedef TimeTest<T> = bool Function(T);

class TimeModel {
  bool allDayMode;
  DateTime time;

  TimeModel(this.allDayMode, this.time);

  @override
  bool operator ==(Object other) =>
      identical(this, other) ||
      other is TimeModel &&
          runtimeType == other.runtimeType &&
          allDayMode == other.allDayMode &&
          time == other.time;

  @override
  int get hashCode => allDayMode.hashCode ^ time.hashCode;
}

const int MODE_NEVER = 5;
const int MODE_DAILY = 1;
const int MODE_WEEKLY = 2;
const int MODE_MONTHLY = 3;
const int MODE_YEARLY = 4;

int getRecurrenceMode(RecurrenceRule rule) {
  switch (rule.recurrenceFrequency) {
    case RecurrenceFrequency.Daily:
      return MODE_DAILY;
    case RecurrenceFrequency.Weekly:
      return MODE_WEEKLY;
    case RecurrenceFrequency.Monthly:
      return MODE_MONTHLY;
    case RecurrenceFrequency.Yearly:
      return MODE_YEARLY;
    default:
      return MODE_NEVER;
  }
}
